#ifndef _FREE_DATABASE_WRAP_
#define _FREE_DATABASE_WRAP_

#include "node.h"
#include "v8.h"
#include <vector>

#include "udataset/mdb/CommonStruct.h"
#include "udataset/mdb/ModelTree.h"
#include "kernel/unicodestring.h"
#include "kernel/utf8string.h"
#include "kernel/multibytestring.h"

using namespace std;
using namespace v8;
using namespace FD::Utility::Dataset;

#undef String

namespace freedatabase
{
/**
	* 将utf8转成gbk编码
	* */
string utf82gbk(char *ori)
{
	FD::Kernel::FdMultiByteString::CharSet cs = FD::Kernel::FdMultiByteString::CS_UTF8;
	FD::Kernel::FdGbkString gbkName(ori, cs);
	return gbkName.c_str();
}
/**
	* 将gbk转成utf8编码
	* */
string gbk2utf8(char *ori)
{
	FD::Kernel::FdUtf8String ustr(ori);
	return ustr.c_str();
}

/**
		 * 将PModelInfo对象转换成v8::Object
		* */
Local<Object> PModelInfo2Object(Isolate *isolate, PModelInfo *info)
{
	Local<Object> obj = Object::New(isolate);
	obj->Set(v8::String::NewFromUtf8(isolate, "modelID"), v8::Number::New(isolate, info->modelID));
	obj->Set(v8::String::NewFromUtf8(isolate, "modelName"), v8::String::NewFromUtf8(isolate, gbk2utf8(info->modelName).c_str()));
	return obj;
}

/**
		 * 将PModelInfoVec对象转换成v8::Array
		* */
Local<Array> PModelInfoVec2Array(Isolate *isolate, PModelInfoVec *vec)
{
	Local<Array> infoVec = Array::New(isolate);
	vector<PModelInfo>::iterator it;
	long index = 0;

	for (it = vec->begin(); it != vec->end(); it++)
	{
		infoVec->Set(index, PModelInfo2Object(isolate, &*it));
		index++;
	}
	return infoVec;
}

/**
		* 将SimpleBound对象转成v8::Object
		* */
Local<Object> SimpleBound2Object(Isolate *isolate, SimpleBound bound)
{
	Local<Object> obj = Object::New(isolate);
	obj->Set(v8::String::NewFromUtf8(isolate, "minX"), v8::Number::New(isolate, bound.minX));
	obj->Set(v8::String::NewFromUtf8(isolate, "minY"), v8::Number::New(isolate, bound.minY));
	obj->Set(v8::String::NewFromUtf8(isolate, "minZ"), v8::Number::New(isolate, bound.minZ));
	obj->Set(v8::String::NewFromUtf8(isolate, "maxX"), v8::Number::New(isolate, bound.maxX));
	obj->Set(v8::String::NewFromUtf8(isolate, "maxY"), v8::Number::New(isolate, bound.maxY));
	obj->Set(v8::String::NewFromUtf8(isolate, "maxZ"), v8::Number::New(isolate, bound.maxZ));
	return obj;
}
Local<Array> ModelTreeSet2Array(Isolate *isolate, std::set<ModelTree *> treeset);
/**
		* 将ModelTree对象转成v8::Object
		* */
Local<Object> ModelTree2Object(Isolate *isolate, ModelTree *tree)
{
	Local<Object> obj = Object::New(isolate);
	obj->Set(v8::String::NewFromUtf8(isolate, "nodeName"), v8::String::NewFromUtf8(isolate, gbk2utf8(tree->nodeName).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "nodeGuid"), v8::String::NewFromUtf8(isolate, gbk2utf8(tree->nodeGuid).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "nodeGuid2"), v8::String::NewFromUtf8(isolate, gbk2utf8(tree->nodeGuid2).c_str()));
	//obj->Set(v8::String::NewFromUtf8(isolate, "tileNo"), v8::Number::New(isolate, tree->tileNo));
	obj->Set(v8::String::NewFromUtf8(isolate, "parentNodeGuid"), v8::String::NewFromUtf8(isolate, gbk2utf8(tree->parentNodeGuid).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "nodeBound"), SimpleBound2Object(isolate, tree->nodeBound));
	if (tree->mpParent != NULL)
	{
		obj->Set(v8::String::NewFromUtf8(isolate, "mpParent"), ModelTree2Object(isolate, tree->mpParent));
	}
	obj->Set(v8::String::NewFromUtf8(isolate, "mChildren"), ModelTreeSet2Array(isolate, tree->mChildren));
	return obj;
}

/**
		* 将ModelTreeVec对象转成v8::Array
		* */
Local<Array> ModelTreeVec2Array(Isolate *isolate, ModelTreeVec treevec)
{
	Local<Array> treeVec = Array::New(isolate);
	ModelTreeVec::iterator it;
	long index = 0;
	for (it = treevec.begin(); it != treevec.end(); it++)
	{
		treeVec->Set(index, ModelTree2Object(isolate, *it));
		index++;
	}
	return treeVec;
}
/**
		* 将ModelTreeSet对象转成v8::Array
		* */
Local<Array> ModelTreeSet2Array(Isolate *isolate, std::set<ModelTree *> treeset)
{
	Local<Array> treeVec = Array::New(isolate);
	std::set<ModelTree *>::iterator it;
	long index = 0;
	for (it = treeset.begin(); it != treeset.end(); it++)
	{
		treeVec->Set(index, ModelTree2Object(isolate, *it));
		index++;
	}
	return treeVec;
}

/**
		* 将PropertySet对象转成v8::Object
		* */
Local<Object> PropertySet2Object(Isolate *isolate, PropertySet *propset)
{
	Local<Object> obj = Object::New(isolate);
	obj->Set(v8::String::NewFromUtf8(isolate, "Name"), v8::String::NewFromUtf8(isolate, gbk2utf8(propset->name).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "id"), v8::String::NewFromUtf8(isolate, gbk2utf8(propset->guid).c_str()));

	Local<Array> keyVal = Array::New(isolate);
	uint32 index = 0;
	std::vector<pair<FD::Kernel::String, FD::Kernel::String>>::iterator it;
	for (it = propset->keyVal.begin(); it != propset->keyVal.end(); it++)
	{
		Local<Object> prop = Object::New(isolate);
		prop->Set(v8::String::NewFromUtf8(isolate, "Name"), v8::String::NewFromUtf8(isolate, gbk2utf8((*it).first).c_str()));
		prop->Set(v8::String::NewFromUtf8(isolate, "NominalValue"), v8::String::NewFromUtf8(isolate, gbk2utf8((*it).second).c_str()));
		keyVal->Set(index, prop);
		index++;
	}
	obj->Set(v8::String::NewFromUtf8(isolate, "sValue"), keyVal);
	return obj;
}

/**
		* 将PropertySetVec对象转成v8::Array
		* */
Local<Array> PropertySetVec2Array(Isolate *isolate, PropertySetVec *propvec)
{
	Local<Array> arr = Array::New(isolate);
	uint32 index = 0;
	PropertySetVec::iterator it;
	for (it = propvec->begin(); it != propvec->end(); it++)
	{
		arr->Set(index, PropertySet2Object(isolate, &*it));
		index++;
	}
	return arr;
}

/**
		* 将CompTypeAttr对象转成v8::Object
		* */
Local<Object> CompTypeAttr2Object(Isolate *isolate, CompTypeAttr *attr)
{
	Local<Object> obj = Object::New(isolate);
	obj->Set(v8::String::NewFromUtf8(isolate, "name"), v8::String::NewFromUtf8(isolate, gbk2utf8(attr->name).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "guid"), v8::String::NewFromUtf8(isolate, gbk2utf8(attr->guid).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "tag"), v8::String::NewFromUtf8(isolate, gbk2utf8(attr->tag).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "predefinedType"), v8::String::NewFromUtf8(isolate, gbk2utf8(attr->predefinedType).c_str()));

	obj->Set(v8::String::NewFromUtf8(isolate, "proSetVec"), PropertySetVec2Array(isolate, &(attr->proSetVec)));
	return obj;
}

/**
		* 将OpeningElem对象转成v8::Object
		* */
Local<Object> OpeningElem2Object(Isolate *isolate, OpeningElem *elem)
{
	Local<Object> obj = Object::New(isolate);
	obj->Set(v8::String::NewFromUtf8(isolate, "name"), v8::String::NewFromUtf8(isolate, gbk2utf8(elem->name).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "guid"), v8::String::NewFromUtf8(isolate, gbk2utf8(elem->guid).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "objectType"), v8::String::NewFromUtf8(isolate, gbk2utf8(elem->objectType).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "objectPlacement"), v8::String::NewFromUtf8(isolate, gbk2utf8(elem->objectPlacement).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "layerGuid"), v8::String::NewFromUtf8(isolate, gbk2utf8(elem->layerGuid).c_str()));

	obj->Set(v8::String::NewFromUtf8(isolate, "proSetVec"), PropertySetVec2Array(isolate, &(elem->proSetVec)));
	return obj;
}

/**
		* 将LinkOpenings对象转成v8::Array
		* */
Local<Array> LinkOpenings2Array(Isolate *isolate, LinkOpenings *links)
{
	Local<Array> arr = Array::New(isolate);
	uint32 index = 0;
	LinkOpenings::iterator it;
	for (it = links->begin(); it != links->end(); it++)
	{
		arr->Set(index, OpeningElem2Object(isolate, &*it));
		index++;
	}
	return arr;
}

/**
		* 将CompAttr对象转成v8::Object
		* */
Local<Object> CompAttr2Object(Isolate *isolate, CompAttr *attr)
{
	Local<Object> obj = Object::New(isolate);
	obj->Set(v8::String::NewFromUtf8(isolate, "Name"), v8::String::NewFromUtf8(isolate, gbk2utf8(attr->name).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "id"), v8::String::NewFromUtf8(isolate, gbk2utf8(attr->guid).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "ObjectType"), v8::String::NewFromUtf8(isolate, gbk2utf8(attr->objectType).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "ObjectPlacement"), v8::String::NewFromUtf8(isolate, gbk2utf8(attr->objectPlacement).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "layerGuid"), v8::String::NewFromUtf8(isolate, gbk2utf8(attr->layerGuid).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "Tag"), v8::String::NewFromUtf8(isolate, gbk2utf8(attr->tag).c_str()));

	obj->Set(v8::String::NewFromUtf8(isolate, "linkOpenings"), LinkOpenings2Array(isolate, &(attr->linkOpenings)));
	obj->Set(v8::String::NewFromUtf8(isolate, "linkCompType"), CompTypeAttr2Object(isolate, &(attr->linkCompType)));
	obj->Set(v8::String::NewFromUtf8(isolate, "propset"), PropertySetVec2Array(isolate, &(attr->proSetVec)));
	return obj;
}

/**
		* 将CompInfo对象转成v8::Object
		* */
Local<Object> CompInfo2Object(Isolate *isolate, CompInfo *cinfo)
{
	Local<Object> obj = Object::New(isolate);
	obj->Set(v8::String::NewFromUtf8(isolate, "name"), v8::String::NewFromUtf8(isolate, gbk2utf8(cinfo->name).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "guid"), v8::String::NewFromUtf8(isolate, gbk2utf8(cinfo->guid).c_str()));
	return obj;
}

/**
		* 将CompInfoVec对象转成v8::Array
		* */
Local<Array> CompInfoVec2Array(Isolate *isolate, CompInfoVec *infovec)
{
	Local<Array> arr = Array::New(isolate);
	uint32 index = 0;
	CompInfoVec::iterator it;
	for (it = infovec->begin(); it != infovec->end(); it++)
	{
		arr->Set(index, CompInfo2Object(isolate, &*it));
		index++;
	}
	return arr;
}

/**
	* 将CompType对象转成v8::Object
	* */
Local<Object> CompType2Object(Isolate *isolate, CompType *ctype)
{
	Local<Object> obj = Object::New(isolate);
	obj->Set(v8::String::NewFromUtf8(isolate, "name"), v8::String::NewFromUtf8(isolate, gbk2utf8(ctype->name).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "typeID"), v8::Number::New(isolate, ctype->typeID));
	return obj;
}
/**
	* 将CompTypeVec对象转成v8::Array
	* */
Local<Array> CompTypeVec2Array(Isolate *isolate, CompTypeVec *typevec)
{
	Local<Array> arr = Array::New(isolate);
	uint32 index = 0;
	CompTypeVec::iterator it;
	for (it = typevec->begin(); it != typevec->end(); it++)
	{
		arr->Set(index, CompType2Object(isolate, &*it));
		index++;
	}
	return arr;
}

/**
	* 将Task对象转成v8::Object
	* */
Local<Object> Task2Object(Isolate *isolate, Task *task)
{
	Local<Object> obj = Object::New(isolate);
	obj->Set(v8::String::NewFromUtf8(isolate, "taskName"), v8::String::NewFromUtf8(isolate, gbk2utf8(task->taskName).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "taskID"), v8::Number::New(isolate, task->taskID));
	obj->Set(v8::String::NewFromUtf8(isolate, "parentTaskID"), v8::Number::New(isolate, task->parentTaskID));
	obj->Set(v8::String::NewFromUtf8(isolate, "planS"), v8::String::NewFromUtf8(isolate, gbk2utf8(task->planS.toString()).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "planE"), v8::String::NewFromUtf8(isolate, gbk2utf8(task->planE.toString()).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "actualS"), v8::String::NewFromUtf8(isolate, gbk2utf8(task->actualS.toString()).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "actualE"), v8::String::NewFromUtf8(isolate, gbk2utf8(task->actualE.toString()).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "taskType"), v8::Number::New(isolate, task->taskType));
	obj->Set(v8::String::NewFromUtf8(isolate, "guid"), v8::String::NewFromUtf8(isolate, gbk2utf8(task->guid).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "totalPrice"), v8::Number::New(isolate, task->totalPrice));
	obj->Set(v8::String::NewFromUtf8(isolate, "desc"), v8::String::NewFromUtf8(isolate, gbk2utf8(task->desc).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "bActive"), v8::Boolean::New(isolate, task->bActive));
	obj->Set(v8::String::NewFromUtf8(isolate, "percent"), v8::Number::New(isolate, task->percent));
	return obj;
}
/**
	* 将TaskVec对象转成v8::Array
	* */
Local<Array> TaskVec2Array(Isolate *isolate, TaskVec *typevec)
{
	Local<Array> arr = Array::New(isolate);
	uint32 index = 0;
	TaskVec::iterator it;
	for (it = typevec->begin(); it != typevec->end(); it++)
	{
		arr->Set(index, Task2Object(isolate, &*it));
		index++;
	}
	return arr;
}

// uint32 floorFDID;
// String guid;
// String name;
// String objectPlacement;
// String longName;
// String compositionType;
// String elevation;

/**
 * 楼层信息转成V8对象
 * */
Local<Object> Floor2Object(Isolate *isolate, Floor *floor)
{
	Local<Object> obj = Object::New(isolate);
	obj->Set(v8::String::NewFromUtf8(isolate, "floorFDID"), v8::Number::New(isolate, floor->floorFDID));
	obj->Set(v8::String::NewFromUtf8(isolate, "guid"), v8::String::NewFromUtf8(isolate, gbk2utf8(floor->guid).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "name"), v8::String::NewFromUtf8(isolate, gbk2utf8(floor->name).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "objectPlacement"), v8::String::NewFromUtf8(isolate, gbk2utf8(floor->objectPlacement).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "longName"), v8::String::NewFromUtf8(isolate, gbk2utf8(floor->longName).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "compositionType"), v8::String::NewFromUtf8(isolate, gbk2utf8(floor->compositionType).c_str()));
	obj->Set(v8::String::NewFromUtf8(isolate, "elevation"), v8::String::NewFromUtf8(isolate, gbk2utf8(floor->elevation).c_str()));
	return obj;
}
/**
 * 楼层信息数组转成V8数组
 * */
Local<Array> Floors2Array(Isolate *isolate, Floors *floors)
{
	Local<Array> arr = Array::New(isolate);
	uint32 index = 0;
	Floors::iterator it;
	for (it = floors->begin(); it != floors->end(); it++)
	{
		arr->Set(index, Floor2Object(isolate, &*it));
		index++;
	}
	return arr;
}

} // namespace freedatabase

#endif
